package com.stu.filter;

import com.alibaba.fastjson.JSONObject;
import com.stu.constant.JwtClaimsConstant;
import com.stu.context.BaseContext;
import com.stu.result.Result;
import com.stu.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.IOException;

@Slf4j
//@WebFilter(urlPatterns = "/*")：这是一个Servlet 3.0规范中的注解，它用于将DemoFilter类声明为一个Web过滤器，并指定它应用于所有URL路径（/*）。
@WebFilter(urlPatterns = "/*")
public class filter implements Filter {

    public filter() {
    }

    @Override //每拦截到请求后就会被调用一次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {


        System.out.println("当前线程的id：" + Thread.currentThread().getId());

        HttpServletRequest req = (HttpServletRequest) servletRequest;//强制转换类型
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        //log.info("req:{}",req.getHeader().toString());

        //获取请求url
        String url = req.getRequestURI().toString();
        log.info("请求的url：{}",url);
        //判断url是否含login
        if(url.contains("login")){
            filterChain.doFilter(servletRequest, servletResponse);//如果是login的请求应当直接放行
            return;
        }
        //放行OPTIONS请求
        String method = req.getMethod();
        if ("OPTIONS".equals(method)) {
            log.info("放行请求头：{}",method);
            filterChain.doFilter(servletRequest,servletResponse);
            return ;
        }
        //获取请求头中的令牌（token），令牌一般放在请求头中的token中
        String jwt = req.getHeader("token");
        log.info("jwt:{}",jwt);

        //判断令牌是否存在
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头为空");
            Result error = Result.error("token is null");
            //转换对象成json
            String notlogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notlogin);
            filterChain.doFilter(servletRequest,servletResponse);

            return;
        }
        //解析token，判断结果
        try {
            log.info("jwt校验:{}", jwt);
            //调用解析令牌的函数
            Claims claims = JwtUtils.parseJWT(jwt);
            log.info("claims:{}",claims);

            Long empId;
            Long role;

            //判断是学生还是管理员
            if(url.contains("student")){
                //解析令牌（令牌内含操作者的信息）获取到员工id
                empId = Long.valueOf(claims.get(JwtClaimsConstant.STU_ID).toString());
                role = Long.valueOf(claims.get("role").toString());

                log.info("当前学生id：{}", empId);
            }else{
                //解析令牌（令牌内含操作者的信息）获取到员工id
                empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
                role = Long.valueOf(claims.get("role").toString());
                log.info("当前员工id：{}", empId);

            }
            //存储员工id
            BaseContext.setCurrentId(empId);
            BaseContext.setRole(role);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析令牌失败，返回未登录的错误信息");
            Result error = Result.error("Password or Account is error");
            //转换对象成json
            String notlogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notlogin);
            return;
        }

        //放行请求
        log.info("令牌合法");
        filterChain.doFilter(servletRequest,servletResponse);
    }

}
